/**
 * 
 */
package com.gr.staffpm.pages.schedule;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gr.staffpm.gof.observer.Subscribable;
import com.gr.staffpm.gof.observer.Subscriber;
import com.gr.staffpm.google.utils.GCalUtils;
import com.gr.staffpm.pages.schedule.model.Event;
import com.gr.staffpm.security.service.UserService;
import com.gr.staffpm.tasks.service.TaskService;
import com.gr.staffpm.utils.ListSortUtils;


/**
 * @author Graham Rhodes 30 Mar 2011 20:25:54
 */
public class WeekView extends Panel implements Subscribable {

    @SpringBean(name = "taskService")
    private TaskService taskService;
    @SpringBean(name = "userService")
    private UserService userService;
    private static final long serialVersionUID = 1L;
    private final List<Subscriber> subscribers = new ArrayList<Subscriber>();
    private final RepeatingView weekBGRows = new RepeatingView("weekBGRows");
    private final RepeatingView dayTimes = new RepeatingView("dayTimes");
    private final List<WeekViewEventPanel> eventPanels = new ArrayList<WeekViewEventPanel>();
    private DateTime viewStart, viewEnd;
    private final Schedule schedule;
    private final Logger log = LoggerFactory.getLogger(getClass());

    public WeekView(String id, Schedule schedule) {
        super(id);
        this.schedule = schedule;

        WeekViewEventPanel eventPanel1 = new WeekViewEventPanel("eventPanel1");
        add(eventPanel1);
        WeekViewEventPanel eventPanel2 = new WeekViewEventPanel("eventPanel2");
        add(eventPanel2);
        WeekViewEventPanel eventPanel3 = new WeekViewEventPanel("eventPanel3");
        add(eventPanel3);
        WeekViewEventPanel eventPanel4 = new WeekViewEventPanel("eventPanel4");
        add(eventPanel4);
        WeekViewEventPanel eventPanel5 = new WeekViewEventPanel("eventPanel5");
        add(eventPanel5);
        WeekViewEventPanel eventPanel6 = new WeekViewEventPanel("eventPanel6");
        add(eventPanel6);
        WeekViewEventPanel eventPanel7 = new WeekViewEventPanel("eventPanel7");
        add(eventPanel7);
        eventPanels.add(eventPanel1);
        eventPanels.add(eventPanel2);
        eventPanels.add(eventPanel3);
        eventPanels.add(eventPanel4);
        eventPanels.add(eventPanel5);
        eventPanels.add(eventPanel6);
        eventPanels.add(eventPanel7);

        updateView(new DateTime());

        add(weekBGRows);
        add(dayTimes);
    }

    /**
     * updates the week view with the specified date
     * @param date
     *          a DateTime
     */
    void updateView(DateTime date) {

        if (date.getDayOfWeek() != 7)
            date = date.minusDays(date.getDayOfWeek());

        viewStart = date;
        viewEnd = viewStart.plusDays(7);

        List<Event> weekEvents = taskService.getTasksDueBetweenForUser(schedule, userService.getCurrentUser(), viewStart, viewEnd);
        if (userService.getCurrentUser().isGcalEnabled() && (userService.getCurrentUser().getGcalAuth() != null)) {
            weekEvents.addAll(GCalUtils.getAndProcessGcalEvents(schedule, userService, viewStart, viewEnd));
        } else if (userService.getCurrentUser().isGcalEnabled() && (userService.getCurrentUser().getGcalAuth() == null)) {
            log.info("You have not autorised staffpm to access your google account.");
        }
        WeekRow weekRow = new WeekRow("weekRow", true, viewStart, date, weekEvents) {

            private static final long serialVersionUID = 1L;

            @Override
            protected void onComponentTag(ComponentTag tag) {
                tag.getAttributes().put("style", "height: 100%; top: 0pt; left: 51px; width: 96.5%;");
                tag.getAttributes().put("class", "ext-cal-wk-ct");
            }

        };
        weekRow.setWeekNumberVisible(false);
        addOrReplace(weekRow);

        dayTimes.removeAll();
        weekBGRows.removeAll();
        for (int hour = 0; hour <= date.hourOfDay().getMaximumValue(); hour++) {
            weekBGRows.add(new DayTimeBackgroundPanel(String.valueOf(hour)));
            int hourTime = hour % 12;
            String hourLabel = (hourTime == 0 ? "12" : hourTime) + ((hour < 12) ? "am" : "pm");
            dayTimes.add(new DayTimeRow(String.valueOf(hour), hourLabel));
        }

        List<List<Event>> eventDays = ListSortUtils.sortEventsByDayAndLength(weekEvents, viewStart, false, true);
        for (int day = 0; day < eventDays.size(); day++) {
            eventPanels.get(day).removeAllEvents();
            for (Event event : eventDays.get(day)) {
                String id = RandomStringUtils.randomNumeric(10);
                eventPanels.get(day).addEvent(id, event);
            }
        }
    }

    @Override
    public void addSubscriber(Subscriber subscriber) {
        subscribers.add(subscriber);
    }

    @Override
    public void notifySubscribers(Object object, AjaxRequestTarget target) {
        for (Subscriber subscriber : subscribers) {
            subscriber.notifySubscriber(object, target);
        }
    }

    public DateTime getViewStart() {
        return viewStart;
    }

    public DateTime getViewEnd() {
        return viewEnd;
    }

}
